Ast和babel学习记录

Babel 中文网: https://www.babeljs.cn/docs/
<!– Babel Handbook: https://github.com/jamiebuilds/babel-handbook?spm=a2c6h.12873639.article-detail.21.20ae2384l3nF8E

A guided handbook on how to use Babel and how to create plugins for Babel.
PS: 下面两个具体的手册内容。
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/README.md
–>
Babel 用户手册: https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/user-handbook.md

Babel 插件手册: https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#writing-your-first-babel-plugin

@babel/types: https://babeljs.io/docs/en/babel-types

2022.9.1 星期 :

# ast 介绍
<!– # 1 babel和ast(实现简单的babel插件)

–>

AST简介

抽象语法树(abstract syntax trees),就是将代码转换成的⼀种抽象的树形结构,通常是 JSON描述。
AST 并不是哪个编程语⾔特有的概念,在前端领域,⽐较常⽤的 AST ⼯具如esprima,babel(babylon
) 的解析模块,其他如 Vue ⾃⼰实现的模板解析器。

AST Explorer: https://astexplorer.net
<!–
推荐⼯具: AST 在线学习tokens 在线分析
PS: tokens 在线分析 打不开。
插件集合(注意,前端 AST 并不仅针对 JavaScript,CSS、HTML ⼀样具有相应的解析⼯具,JavaScript 重点关注)

功能插件常用方法
ast 解析esprima @babel/parser recast.parse
ast 遍历estraverse @babel/traverserecast.visit
⽣成代码escodegen @babel/generatorrecast.print recast.prettyPrint

–>

代码的编译流程

AST与 V8 引擎的编译过程
上述过程分为三部分:解析(parse),转换(transform),⽣成(generate),其中 scanner 部分叫做词法(syntax)分析,parser 部分叫做语法(grammar)分析。
显然,词法分析的结果是 tokens,语法分析得到的就是 AST。

  • 可⻅词法分析,旨在将源代码按照⼀定的分隔符(空格/tab/换⾏等)、注释进⾏分割,并将各个部分进⾏分类构造出⼀段 token 流。
  • ⽽语法分析,则基于 tokens 将源码语义化、结构化为⼀段 JOSN 描述(AST)。反之,如果给出⼀段代码的描述信息,我们也是可以还原源码的。

AST 的节点类型

在操作 AST 过程中,源码部分集中在 Program 对象的 body 属性下,每个节点有着统⼀固定的格式:
@babel/core 依赖了 parser、traverse、generator 模块,所以安装 @babel/core 即可。

traverse ⽅法帮我们处理了 ast 的遍历过程,对于不同节点的处理只需要维护⼀份 types 对应的⽅法即可。进⼀步的,构造 CONSOLE_AST 节点也有⼏种⽅式。先使⽤在线⼯具将 console.log('函数执⾏完成'); 结构化(如果你已经⼗分熟悉这个过程,可以跳过):

  • 基础⽅式——使⽤ @babel/types 来构造语句
  • 终极简化版——模板 API

AST 与 babel 插件

官⽅插件
随着 ECMAScript 的发展,不断涌出⼀些新的语⾔特性(如管道操作符、可选链操作符、控制合并操作符……),也包括但不限于 JSX 语法等。遇到 babel 本身的解析引擎模块不能识别新特性的问题,可以由插件来处理。

运⾏上⾯的代码会直接报错,源码(第 5 ⾏)使⽤的管道操作符处于提案中,需要借助插件来解析:

  1. @babel/parser 模块 + 内联配置(记得安装 @babel/plugin-proposal-pipeline-operator )解析
  2. @babel/core模块 + ⽂件 babel.config.json 解析(babel 会⾃动到项⽬⽬录查找最近的)babel配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* ## 1  */
const ast = babel.parse(code, {
sourceType: 'module',
plugins:[
["pipelineOperator", {
"proposal": "hack",
"topicToken": "^^"
}]
]
});
/* ## 2 */
{
"plugins": [
["@babel/plugin-proposal-pipeline-operator", {
"proposal": "hack",
"topicToken": "^^"
}]
]
}
//输出
const square = x => x ** 2;
const sum = a => a + 2;
const list = sum(square(5));

当项⽬需要⽀持的语⾔特性越来越多, plugins 需要逐⼀添加,为了解决插件的管理与依赖问题,通过提供常⽤的环境配置。

  • 代码转换
  • Code2Code
    <!– 以 Vue To React 为例,大致过程跟ES6 => ES5类似,通过vue-template-compiler编译得到 Vue AST => 转换为 React AST => 输出 React 代码。

有兴趣的同学可以参考vue-to-react

其他多端框架:一份代码 => 多端,大体思路一致。
–>

babel path操作

### path
其中path指的是两个节点的连接,其中可以访问节点信息,也包含相关增删改查方法,类似于DOM操作,其中path上的操作是操作子节点,想操作父节点可以使用path.parentPath


插入相邻节点
插入进一个数组类型节点



可以通过.node获取
也可以.get

### state

# babel插件实践

babel插件实例

# Babylon

Babylon

项目主页地址:https://babeljs.io/
项目仓库地址: https://github.com/babel/babylon

Babylon is a JavaScript parser used in Babel.

Heavily based on acorn and acorn-jsx, thanks to the awesome work of @RReverser and @marijnh.

knowledge is no pay,reward is kindness
0%